import sys
import argparse
import asyncio
import random
import syndicate
from syndicate import patterns as P, actor, dataspace, turn

from syndicate.schema import sturdy
from preserves.schema import load_schema_file
from pprint import pprint

from multiprocessing import shared_memory

ShmProtocol = load_schema_file('./shm.bin').shm
UseBuffer = ShmProtocol.UseBuffer
Buffer = ShmProtocol.Buffer
Read = ShmProtocol.Read
Commit = ShmProtocol.Commit

parser = argparse.ArgumentParser(description='Allows other actors to open shared memory areas for IPC',
                                 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--address', metavar='\'<tcp "HOST" PORT>\'',
                    help='transport address of the server',
                    default='<ws "ws://localhost:9001/">')
parser.add_argument('--cap', metavar='\'<ref ...>\'',
                    help='capability for the dataspace on the server',
                    default='<ref {oid: "syndicate" sig: #[acowDB2/oI+6aSEC3YIxGg==]}>')
args = parser.parse_args()

@actor.run_system(name = 'shm-producer', debug = False)
def main():
    root_facet = turn.active_facet()

    @syndicate.relay.connect(args.address, sturdy.SturdyRef.decode(syndicate.parse(args.cap)))
    def on_connected(ds):
        turn.on_stop(lambda: turn.stop(root_facet))
        turn.publish(ds, UseBuffer("producer", 8))
        t_size = turn.field(0, "size")

        @dataspace.during(ds, P.rec('Buffer', P.CAPTURE, P.CAPTURE))
        def on_buffer(name, size):
            t_size.value = size
        
        @dataspace.on_message(ds, P.rec('Free', P.CAPTURE))
        def on_free(name):
            print("on free")
            print("opening shm")
            shm = shared_memory.SharedMemory(name, size=t_size.value)
            print("writing shm")
            shm.buf[:5] = b'howdy'
            turn.send(ds, Commit(name))
            turn.on_stop(lambda: print("closing shm"))
            turn.on_stop(lambda: shm.close())
